package com.yuanchu.store.listener;

import com.alibaba.fastjson.JSON;
import com.yuanchu.common.exception.YuanChuException;
import com.yuanchu.store.dto.OrderMessage;
import com.yuanchu.store.service.YoshopCartService;
import com.yuanchu.store.service.YoshopUserBalanceLogService;
import com.yuanchu.store.service.YoshopUserPointsLogService;
import com.yuanchu.store.service.impl.YoshopUserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Map;

import static com.yuanchu.store.config.DearMessageConfig.PAYNOTIFY_STORE_QUEUE;

/**
 * @version: 1.0
 * @Author: adan
 * @description:
 * @date: 2024-02-23 17:08
 */
@Slf4j
@Component
public class OrderListener {

    @Resource
    private YoshopUserBalanceLogService userBalanceLogService;
    @Resource
    private YoshopUserServiceImpl userService;
    @Resource
    private YoshopUserPointsLogService userPointsLogService;
    @Resource
    private YoshopCartService cartService;
    @Resource
    private RabbitTemplate rabbitTemplate;

    //监听消息队列接收支付结果通知
    /*@RabbitListener(queues = PAYNOTIFY_STORE_QUEUE)
    public void listenSimpleQueue(String msg) {
        // 接收到消息
        log.info("消费者接收到simple.queue的消息：【{}】", msg);
        OrderMessage message = JSON.parseObject(msg, OrderMessage.class);
        // 1、记录支付日志
        boolean userBalanceLog = userBalanceLogService.insertUserBalanceLog(
                userId, scene, orderNo, message.getPayPrice(), message.getStoreId());
        if (!userBalanceLog) {
            throw new YuanChuException("更新用户余额日志失败");
        }
        // 2、清空购物车数据
        if (!StringUtils.isEmpty(message.getCartIds())){
            boolean delCartGoods = cartService.delCartGoods(userId, message.getCartIds(), message.getStoreId());
            if (!delCartGoods) {
                throw new YuanChuException("清空购物车数据失败");
            }
        }
        log.info("消息处理完成！");
    }*/




    // @RabbitListener(bindings = @QueueBinding(
    //         value = @Queue(name = PAYNOTIFY_STORE_QUEUE),
    //         exchange = @Exchange(name = "paynotify_exchange_direct"),
    //         key = {"store"}
    // ))

    //监听消息队列接收支付结果通知
    @RabbitListener(queues = PAYNOTIFY_STORE_QUEUE)
    public void listenSimpleQueue(String msg) {
        // 接收到消息
        log.info("消费者接收到simple.queue的消息：【{}】", msg);
        OrderMessage message = JSON.parseObject(msg, OrderMessage.class);
        Integer userId = message.getUserId();
        Integer scene = message.getScene();
        String orderNo = message.getOrderNo();
        Integer storeId = message.getStoreId();
        String payPrice = message.getPayPrice();
        Integer orderId = message.getOrderId();
        Integer usePoints = message.getUsePoints();
        String cartIds = message.getCartIds();
        // 1、处理消息, 修改用户余额

        boolean userBalance = userService.deductUserBalance(userId, payPrice, usePoints, storeId);
        if (!userBalance) {
            // throw new YuanChuException("更新用户余额失败");
            log.error("更新用户余额失败,支付失败");
            // 支付成功，更新订单状态, 付款状态(10未付款 20已付款)
            sendOrderPayStatusMessage(orderId, 10);
        }
        // 3、记录支付日志
        boolean userBalanceLog = userBalanceLogService.insertUserBalanceLog(
                userId, scene, orderNo, payPrice, storeId);
        if (!userBalanceLog) {
            throw new YuanChuException("更新用户余额日志失败");
        }
        // 2、记录用户积分日志
        if (usePoints > 0){
            boolean pointsLog = userPointsLogService.decrUserPoints(userId, scene, usePoints, orderNo, storeId);
            if (!pointsLog) {
                throw new YuanChuException("更新用户积分日志失败");
            }
        }
        // 3、清空购物车数据
        if (!StringUtils.isEmpty(cartIds)){
            boolean delCartGoods = cartService.delCartGoods(userId, cartIds, storeId);
            if (!delCartGoods) {
                throw new YuanChuException("清空购物车数据失败");
            }
        }
        log.info("消息处理完成！");
    }

    private void sendOrderPayStatusMessage(Integer orderId, Integer payStatus) {
        Map<String, Object> map = new java.util.HashMap<>();
        map.put("orderId", orderId);
        map.put("payStatus", payStatus);
        // 1.准备消息
        String msg = JSON.toJSONString(map);
        // 2.准备CorrelationData
        // 2.1.消息ID
        CorrelationData correlationData = new CorrelationData(String.valueOf(orderId));
        Message msgObj = MessageBuilder.withBody(msg.getBytes(StandardCharsets.UTF_8))
                .setDeliveryMode(MessageDeliveryMode.PERSISTENT)
                .build();
        // 2.2.准备ConfirmCallback
        correlationData.getFuture().addCallback(result -> {
            // 判断结果
            if (result.isAck()) {
                // ACK
                log.info("消息成功投递到交换机！消息ID: {}", correlationData.getId());
            } else {
                // NACK
                log.error("消息投递到交换机失败！消息ID：{}", correlationData.getId());
                // 重发消息
            }
        }, ex -> {
            // 记录日志
            log.error("消息发送失败！", ex);
            // 重发消息
        });

        // 3.发送消息
        rabbitTemplate.convertAndSend("paynotify_order_direct", "order.status", msgObj, correlationData);
    }


}
